﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SCRUM.Core.BusinessObjects;

namespace SCRUM.Core.BusinessObjects
{
    /// <summary>
    /// Business object for sprint.
    /// </summary>
    [Serializable()]
    public class Sprint : DescriptedBusinessObject
    {
        /// <summary>
        /// Gets or sets the superior item's ID.
        /// </summary>
        /// <value>The superior item ID.</value>
        public override int SuperiorItemID
        {
            get { return this.ReleaseID; }
            set { this.ReleaseID = value; }
        }

        /// <summary>
        /// Gets or sets from date.
        /// </summary>
        /// <value>From date.</value>
        public DateTime FromDate { get; set; }

        /// <summary>
        /// Gets or sets to date.
        /// </summary>
        /// <value>Duration to date.</value>
        public DateTime ToDate { get; set; }

        /// <summary>
        /// Gets or sets the percentege of technical estimation.
        /// </summary>
        /// <value>The technical estimation.</value>
        public int TechnicalEstimation { get; set; }

        /// <summary>
        /// Gets or sets the percentege of functional estimation.
        /// </summary>
        /// <value>The functional estimation.</value>
        public int FunctionalEstimation { get; set; }

        /// <summary>
        /// Gets or sets the percentege of other estimation.
        /// </summary>
        /// <value>The other estimation.</value>
        public int OtherEstimation { get; set; }

        /// <summary>
        /// Gets or sets the release ID.
        /// </summary>
        /// <value>The release ID.</value>
        public int ReleaseID { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="Sprint"/> class.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <param name="name">The name of the sprint.</param>
        /// <param name="description">The description.</param>
        /// <param name="state">The state.</param>
        /// <param name="fromDate">From date.</param>
        /// <param name="toDate">Duration to date.</param>
        public Sprint(int id, string name, string description, int stateID, DateTime fromDate, DateTime toDate
            , double estimation, double progress, DateTime change, int funcEst, int techEst, int othrEst, int releaseID)
            :base(id,name,description,estimation,progress,change,stateID)
        {
            this.stateType = State.StateTypes.Sprint;
            this.FromDate = fromDate;
            this.ToDate = toDate;
            this.FunctionalEstimation = funcEst;
            this.TechnicalEstimation = techEst;
            this.OtherEstimation = othrEst;
            this.ReleaseID = releaseID;
        }

        /// <summary>
        /// Gets the default length of the sprint = 14 days
        /// </summary>
        /// <value>The default length.</value>
        public static TimeSpan DefaultLength
        {
            get
            {
                return new TimeSpan(14,0,0,0);
            }
        }

        /// <summary>
        /// Gets or sets the release.
        /// </summary>
        /// <value>The release.</value>
        public Release Release
        {
            get
            {
                // Lazy loading
                //if (this.release == null)
                //{
                //    this.release = DAO.DAORelease.GetReleaseBySprintID(this.ID);
                //}
                if (this.release == null)
                {
                    this.Release = DAO.DAORelease.GetReleaseById(this.ReleaseID);
                }
                return this.release;
            }
            set
            {
                this.release = value;
            }
        }

        /// <summary>
        /// Gets or sets the user stories.
        /// </summary>
        /// <value>The user stories.</value>
        public IList<UserStory> UserStories
        {
            get
            {
                // Lazy loading
                if (this.userStories == null)
                {
                    this.userStories = DAO.DAOUserStory.GetAllUserStoriesForSprint(this.ID);
                }
                return this.userStories;
            }
            set
            {
                this.userStories = value;
            }
        }

        /// <summary>
        /// User stories associated to this sprint.
        /// </summary>
        private IList<UserStory> userStories;

        /// <summary>
        /// Release that contains this sprint.
        /// </summary>
        private Release release;
                
        /// <summary>
        /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </returns>
        public override string ToString()
        {
            return this.Name;
        }
    }
}
